library pkg_sand_clock;

import 'dart:math';

import 'package:flutter/material.dart';

/// 沙漏加载动画
class SandClockLoading extends StatefulWidget {
  ///颜色
  final Color color;

  ///大小
  final double size;

  ///动画时间
  final Duration duration;

  SandClockLoading({
    this.color = Colors.black26,
    this.size = 100,
    this.duration = const Duration(seconds: 5),
  });

  @override
  _SandClockLoadingState createState() => _SandClockLoadingState();
}

class _SandClockLoadingState extends State<SandClockLoading>
    with SingleTickerProviderStateMixin {
  late AnimationController controller;
  late Animation animation, rotateAnimation;

  @override
  void initState() {
    controller = AnimationController(
      vsync: this,
      duration: widget.duration,
    )..repeat();

    animation = Tween(begin: 0.0, end: 1.0).animate(
      CurvedAnimation(
        parent: controller,
        curve: Interval(0.0, 0.6, curve: Curves.linear),
      ),
    );

    rotateAnimation = Tween(begin: 0.0, end: pi).animate(
      CurvedAnimation(
        parent: controller,
        curve: Interval(0.6, 1.0, curve: Curves.linear),
      ),
    );
    super.initState();
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: controller,
      builder: (context, child) {
        return Transform.rotate(
          angle: rotateAnimation.value,
          child: SizedBox(
            width: widget.size,
            height: widget.size + widget.size / 2,
            child: CustomPaint(
              painter: _SandClockLoadingPainter(animation.value, widget.color),
            ),
          ),
        );
      },
    );
  }
}

class _SandClockLoadingPainter extends CustomPainter {
  ///进度
  final double progress;

  ///颜色
  final Color color;

  ///画笔
  late Paint _paint;

  ///中间的线的宽度
  double _middleWidth = 2;

  _SandClockLoadingPainter(this.progress, this.color) {
    _paint = Paint()
      ..color = color //画笔颜色
      ..strokeWidth = 2 //画笔粗细
      ..isAntiAlias = true //开启抗锯齿
      ..style = PaintingStyle.stroke; //空心
  }

  @override
  void paint(Canvas canvas, Size size) {
    ///画轮廓
    var path = Path()
      ..moveTo(0, 0)
      ..lineTo(size.width, 0)
      ..lineTo(size.width / 2 + _middleWidth, size.height / 2)
      ..lineTo(size.width, size.height)
      ..lineTo(0, size.height)
      ..lineTo(size.width / 2 - _middleWidth, size.height / 2)
      ..close();
    canvas.drawPath(path, _paint);

    _paint.style = PaintingStyle.fill; //实心
    double offsetX = progress * (size.width / 2 - _middleWidth);
    double offsetY = progress * (size.height / 2);

    ///画三角形
    var topPath = Path()
      ..moveTo(offsetX, offsetY)
      ..lineTo(size.width - offsetX, offsetY)
      ..lineTo(size.width / 2 + _middleWidth, size.height / 2)
      ..lineTo(size.width / 2 - _middleWidth, size.height / 2)
      ..close();
    canvas.drawPath(topPath, _paint);

    ///画底部三角形
    var bottomPath = Path()
      ..moveTo(0, size.height)
      ..lineTo(size.width, size.height)
      ..lineTo(size.width - offsetX, size.height - offsetY)
      ..lineTo(offsetX, size.height - offsetY)
      ..close();
    canvas.drawPath(bottomPath, _paint);

    ///画垂直的线
    _paint.style = PaintingStyle.stroke;
    var linePath = Path()
      ..moveTo(size.width / 2, size.height / 2)
      ..lineTo(size.width / 2, size.height - offsetY)
      ..close();
    canvas.drawPath(linePath, _paint);
  }

  @override
  bool shouldRepaint(covariant _SandClockLoadingPainter oldDelegate) {
    //重新绘制
    return color != oldDelegate.color || progress != oldDelegate.progress;
  }
}
